#pragma once
#include <iostream>
#include <string>
#include <jsoncpp/json/json.h>
using namespace std;
namespace protocol_ns
{
    const string SEP = "\r\n"; // 分隔符
    // 对特定字符串数据添加报头和分隔符
    string Encode(const string &json_str)
    {
        int json_str_len = json_str.size();
        string proto_str = to_string(json_str_len);
        proto_str += SEP;
        proto_str += json_str;
        proto_str += SEP;
        return proto_str;
    }
    string Decode(string &inbuffer)
    {
        //"len"\r\n"{        }\r\n"
        int pos = inbuffer.find(SEP);
        if (pos == string::npos)
        {
            return string();
        }
        string len_str = inbuffer.substr(0, pos);
        if (len_str.empty() == true)
        {
            return string();
        }
        int packlen = stoi(len_str);
        int total = len_str.size() + packlen + SEP.size() * 2;
        if (inbuffer.size() < total)
        {
            return string();
        }
        string package = inbuffer.substr(pos + SEP.size(), total); // 提取有效信息
        inbuffer.erase(0, total);                                  // 移除这次已经读到的信息
        return package;
    }
    // 我们规定协议
    // 报文=报头＋有效载荷
    //"有效载荷长度"\r\n"有效载荷"\r\n
    //"len"\r\n"_x_oper_y"\r\n  ->len是有效载荷的长度,规定\r\n是分隔符，不参与统计
    class Request
    {
    public:
        Request() {}
        Request(int x, int y, char oper)
            : _x(x), _y(y), _oper(oper)
        {
        }
        // 序列化
        bool Serialize(string *out)
        {
            Json::Value root;
            root["x"] = _x;
            root["y"] = _y;
            root["oper"] = _oper;
            Json::FastWriter writer;
            *out = writer.write(root);
            return true;
        }
        // 反序列化
        bool UnSerialize(const string &in)
        {
            Json::Value root;
            Json::Reader reader;
            bool res = reader.parse(in, root);
            if (res == false)
            {
                return false;
            }
            _x = root["x"].asInt();
            _y = root["y"].asInt();
            _oper = root["oper"].asInt();
            return true;
        }

    public:
        int _x;     // 操作数1
        int _y;     // 操作数2
        char _oper; // 运算符
    };

    class Response
    {
    public:
        Response() {}
        Response(int result, int code)
            : _result(result), _code(code)
        {
        }
        // 序列化
        bool Serialize(string *out)
        {
            Json::Value root;
            root["result"] = _result;
            root["code"] = _code;
            Json::FastWriter writer;
            *out = writer.write(root);
            return true;
        }
        // 反序列化
        bool UnSerialize(const string &in)
        {
            Json::Value root;
            Json::Reader reader;
            bool res = reader.parse(in, root);
            if (res == false)
            {
                return false;
            }
            _result = root["result"].asInt();
            _code = root["code"].asInt();
            return true;
        }

    public:
        int _result; // 结果
        int _code;   // 0：成功、1：除0错误、2：非法操作
    };

    class Factory
    {
    public:
        Factory()
        {
            srand(time(nullptr) ^ getpid());
            opers = "+-*/^&|";
        }
        shared_ptr<Request> BulidRequest()
        {
            int x = rand() % 10 + 1;
            usleep(x * 10);
            int y = rand() % 5;
            usleep(y * x * 5);
            char oper = opers[rand() % opers.size()];
            shared_ptr<Request> req = make_shared<Request>(x, y, oper);
            return req;
        }
        shared_ptr<Response> BulidResponse()
        {
            return make_shared<Response>();
        }
        ~Factory()
        {
        }

    private:
        string opers;
    };
}